package com.lalilu.remote.service

import com.lalilu.remote.NetUtils
import com.lalilu.remote.UdpService
import com.lalilu.remote.entity.Host
import com.lalilu.remote.entity.Message
import com.lalilu.remote.toUdpPacket
import com.lalilu.remote.utils.GsonUtils
import java.net.DatagramPacket

class DiscoveryService(
    port: Int,
    bufferSize: Int = 1024,
    private val listener: DiscoveryListener? = null
) : UdpService(port, bufferSize) {

    interface DiscoveryListener {
        fun onNewHostRequestIn(newHost: Host)
        fun onReceiveMessage(message: Message, host: Host)
    }

    fun broadcast(message: Message) {
        val str = GsonUtils.toJson(message)
        broadcast(str.toUdpPacket())
    }

    override suspend fun onReceive(packet: DatagramPacket) {
        if (NetUtils.isLocalHost(packet.address)) {
            return
        }

        val message = packet.data?.runCatching {
            val str = String(this, 0, packet.length).trim()
            GsonUtils.fromJson(str, Message::class.java)
        }?.getOrNull() ?: return

        if (message.deviceName.isEmpty()) {
            return
        }

        val host = message.getHost(packet)

        if (message.request) {
            listener?.onNewHostRequestIn(host)
        }

        listener?.onReceiveMessage(message, host)
    }
}

fun Message.getHost(packet: DatagramPacket): Host {
    return Host(
        port = this.port,
        address = packet.address,
        deviceName = this.deviceName,
    )
}